package cn.pconline.autoclub.service;

import cn.pconline.autoclub.entity.AppConfig;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.gelivable.dao.GeliDao;
import org.gelivable.dao.SqlBuilder;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 应用配置service
 */
public class AppConfigService {

    @Autowired
    private GeliDao dao;
    
    public AppConfig findAppConfig(long configId){
        if(configId<1) return null;
        return dao.find(AppConfig.class, configId);
    }
    public long createAppConfig(AppConfig ac) {
        if (containValue(ac.getAppName(), ac.getAppValue())) {
            throw new IllegalStateException("该配置已经存在");
        }
        long result = dao.create(ac);
        if (result > 0l) {
            flush();
            //syncService.sync(SyncService.ACTION_APPCONFIG);
        }
        return result;
    }

    public int deleteAppConfig(AppConfig ac) {
        int result = dao.delete(ac, ac.getConfigId());
        if (result > 0) {
            flush();
            //syncService.sync(SyncService.ACTION_APPCONFIG);
        }
        return result;
    }

    public int deleteAppConfig(String appName, String appKey) {
        SqlBuilder sql = new SqlBuilder();
        sql.appendSql("DELETE FROM ac_app_config WHERE app_name=").appendValue(appName)
                .appendSql(" AND app_key=").appendValue(appKey);
        int result = dao.getJdbcTemplate().update(sql.getSql(), sql.getValues());
        if (result > 0) {
            flush();
            //syncService.sync(SyncService.ACTION_APPCONFIG);
        }
        return result;
    }

    public int deleteAppConfig(String appName, String appKey, String value) {
        SqlBuilder sql = new SqlBuilder();
        sql.appendSql("DELETE FROM ac_app_config WHERE app_name=").appendValue(appName)
                .appendSql(" AND app_key=").appendValue(appKey)
                .appendSql(" AND app_value=").appendValue(value);
        int result = dao.getJdbcTemplate().update(sql.getSql(), sql.getValues());
        if (result > 0) {
            flush();
            //syncService.sync(SyncService.ACTION_APPCONFIG);
        }
        return result;
    }

    public int updateAppConfig(AppConfig ac) {
        int result = dao.update(ac);
        if (result > 0) {
            flush();
            //syncService.sync(SyncService.ACTION_APPCONFIG);
        }
        return result;
    }

    public int batchUpdateAppConfigByName(List<AppConfig> list) {
        StringBuilder sql = new StringBuilder("UPDATE ac_app_config SET appname = ?, appkey = ?, appvalue = ?  WHERE appname = ? AND appkey = ?");

        //批量插入
        List<Object[]> batch = new ArrayList<Object[]>();
        for (AppConfig ac : list) {
            Object[] VALUES = new Object[]{ac.getAppName(), ac.getAppKey(), ac.getAppValue(),
                ac.getAppName(), ac.getAppKey()};
            batch.add(VALUES);
        }
        int[] result = dao.getJdbcTemplate().batchUpdate(sql.toString(), batch);
        if (result.length > 0) {
            flush();
            //syncService.sync(SyncService.ACTION_APPCONFIG);
        }
        return result.length;
    }

    public List<AppConfig> queryAppConfig(AppConfig ac) {
        SqlBuilder sql = new SqlBuilder();
        sql.appendSql("SELECT * FROM ac_app_config WHERE 1=1 ");
        if (ac.getConfigId() > 0l) {
            sql.appendSql(" AND config_id=").appendValue(ac.getConfigId());
        }
        if (!StringUtils.isEmpty(ac.getAppName())) {
            sql.appendSql(" AND app_name=").appendValue(ac.getAppName());
        }
        if (!StringUtils.isEmpty(ac.getAppKey())) {
            sql.appendSql(" AND app_key=").appendValue(ac.getAppKey());
        }
        if (!StringUtils.isEmpty(ac.getAppValue())) {
            sql.appendSql(" AND app_value=").appendValue(ac.getAppValue());
        }
        return dao.list(AppConfig.class, sql.getSql(), sql.getValues());
    }
    private Map<String, List<AppConfig>> appConfigMap = null;

    /**
     * 刷新缓存，重新读数据库数据
     */
    public void flush() {
        this.loadAppConfig();
    }

    public String getValueByName(String name) {
        String result = null;
        // 先从内存中找
        if (appConfigMap != null) {
            List<AppConfig> configList = appConfigMap.get(name);
            if (configList != null) {
                result = configList.get(0).getAppValue();
            }
        }
        // 从数据库中找
        if (null == result) {
            AppConfig ac = new AppConfig();
            ac.setAppName(name);
            List<AppConfig> list = queryAppConfig(ac);
            if (!list.isEmpty()) {
                result = list.get(0).getAppValue();
            }
        }
        return result;
    }

    public List<String> getValueListByName(String name) {
        List<String> resultList = new ArrayList<String>();
        // 先从内存中找
        if (appConfigMap != null) {
            List<AppConfig> configList = appConfigMap.get(name);
            if (configList != null) {
                for (AppConfig appConfig : configList) {
                    resultList.add(appConfig.getAppValue());
                }
            }
        }

        // 从数据库中找
        if (resultList.isEmpty()) {
            AppConfig ac = new AppConfig();
            ac.setAppName(name);
            List<AppConfig> list = queryAppConfig(ac);
            for (AppConfig app : list) {
                resultList.add(app.getAppValue());
            }
        }
        return resultList;
    }

    public Map<String, String> getValueMapByName(String name) {
        Map<String, String> resultMap = new LinkedHashMap<String, String>();
        // 先从内存中找
        if (appConfigMap != null) {
            List<AppConfig> configList = appConfigMap.get(name);
            if (configList != null) {
                for (AppConfig appConfig : configList) {
                    resultMap.put(appConfig.getAppKey(), appConfig.getAppValue());
                }
            }
        }
        // 从数据库中找
        if (resultMap.isEmpty()) {
            AppConfig ac = new AppConfig();
            ac.setAppName(name);
            List<AppConfig> list = queryAppConfig(ac);
            for (AppConfig app : list) {
                resultMap.put(app.getAppKey(), app.getAppValue());
            }
        }
        return resultMap;
    }

    public List<Map<String, String>> getValueMapListByName(String name) {
        List<Map<String, String>> resultList = new ArrayList<Map<String, String>>();
        // 先从内存中找
        if (appConfigMap != null) {
            List<AppConfig> configList = appConfigMap.get(name);
            if (configList != null) {
                for (AppConfig appConfig : configList) {
                    Map<String, String> appMap = new HashMap<String, String>();
                    appMap.put(appConfig.getAppKey(), appConfig.getAppValue());
                    resultList.add(appMap);
                }
            }
        }
        // 从数据库中找
        if (resultList == null || resultList.isEmpty()) {
            AppConfig ac = new AppConfig();
            ac.setAppName(name);
            List<AppConfig> list = queryAppConfig(ac);
            for (AppConfig appConfig : list) {
                Map<String, String> map = new HashMap<String, String>();
                map.put(appConfig.getAppKey(), appConfig.getAppValue());
                resultList.add(map);
            }
        }
        return resultList;
    }

    public boolean containValue(String name, String value) {
        List<String> result = getValueListByName(name);
        for (String v : result) {
            if (value.equals(v)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 加载应用配置到内存中
     */
    private void loadAppConfig() {
        List<AppConfig> totalList = queryAppConfig(new AppConfig());
        Map<String, List<AppConfig>> appMap = new LinkedHashMap<String, List<AppConfig>>();
        List<AppConfig> appList = new ArrayList<AppConfig>();
        String appName = null;
        for (AppConfig appConfig : totalList) {
            if (appName != null && !appName.equals(appConfig.getAppName())) {
                appMap.put(appName, appList);
                appList = new ArrayList<AppConfig>();
            }
            appList.add(appConfig);
            appName = appConfig.getAppName();
        }
        appMap.put(appName, appList);

        appConfigMap = appMap;
    }
}
